﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.IO;

namespace MTS
{
    [Serializable()]
    public class RenderSettings
    {
        private ImageType tileType;
        private CacheType typeOfCache;
        private string worldPath;
        private byte lightinglevel;
        private byte spectralBlock;
        int bytesPerPixel;
        private bool hell;
        private String cacheDir;

        public ChunkCache getCache()
        {
            if (typeOfCache.Equals(CacheType.SQLITE))
            {
                return new SqlCache(this);
            } else {
                throw new Exception("Not yet implemented " + typeOfCache.ToString());
            }
        }

        public CacheType TypeOfCache
        {
            get
            {
                return typeOfCache;
            }
            set
            {
                this.typeOfCache = value;
            }
        }

        public String CacheDir
        {
            get
            {
                if (cacheDir == null)
                {
                    cacheDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "mts");
                }
                return cacheDir;
            }
            set
            {
                cacheDir = value;
            }
        }

        public ImageType TileType
        {
            get
            {
                return this.tileType;
            }
            set
            {
                this.tileType = value;
            }
        }

        public bool Hell
        {
            get
            {
                return hell;
            }
            set
            {
                hell = value;
            }
        }

        public string WorldPath
        {
            get
            {
                return worldPath;
            }
            set
            {
                worldPath = value;
            }
        }

        public byte LightingLevel
        {
            get
            {
                return this.lightinglevel;
            }
            set
            {
                this.lightinglevel = Math.Max(Math.Min(value, (byte)0xF), (byte)0);
            }
        }

        public byte SpectralBlock
        {
            get
            {
                return this.spectralBlock;
            }
            set
            {
                this.spectralBlock = value;
            }
        }

        public int BytesPerPixel
        {
            get
            {
                return this.bytesPerPixel;
            }
            set
            {
                this.bytesPerPixel = value;
            }
        }

        public override string ToString()
        {
            MD5 hasher = MD5.Create();
            byte[] hash = hasher.ComputeHash(Encoding.Default.GetBytes(WorldPath));
            StringBuilder sBuilder = new StringBuilder();
            string HellString = (Hell ? "H" : String.Empty);
            string bppString = bytesPerPixel.ToString();
            for (int i = 0; i < hash.Length; i++)
            {
                sBuilder.Append(hash[i].ToString("x2"));
            }
            if (TileType.Equals(ImageType.CAVEMAP) || TileType.Equals(ImageType.HEIGHTMAP))
            {
                // Cavemap / Heightmap do not support light levels / spectral analasys
                return Path.Combine(CacheDir, String.Format("{0}", sBuilder), String.Format("T{0}{1}{2}", TileType, HellString, bppString));
            }
            else if (TileType.Equals(ImageType.ISOMETRIC) || TileType.Equals(ImageType.OBLIQUE) || TileType.Equals(ImageType.TERRAIN))
            {
                // Isometric / Oblique / Terrain all support light (or should)
                return Path.Combine(CacheDir, String.Format("{0}", sBuilder), String.Format("T{0}L{1}{2}{3}", TileType, LightingLevel, HellString, bppString));
            }
            else if (TileType.Equals(ImageType.SPECTROGRAPH))
            {
                // No lighting, but has which block has been selected to be rendered
                return Path.Combine(CacheDir, String.Format("{0}", sBuilder), String.Format("T{0}S{1}{2}{3}", TileType, SpectralBlock, HellString, bppString));
            }
            else
            {
                throw new Exception("Invalid tile type " + TileType);
            }
        }
    }
}
